package algorithms.practice;

import java.util.Map;
import java.util.TreeMap;

class P523 {
    private int i;

    public static void main(String[] args) {
        String s = "a";
        //s.substring();

    }
    public String countOfAtoms(String formula) {
        StringBuilder sb = new StringBuilder();
        Map<String, Integer> map = parse(formula);
        for(Map.Entry<String, Integer> entry: map.entrySet()) {
            sb.append(entry.getKey());
            Integer val = entry.getValue();
            sb.append(val == 1 ? "" : val.toString());
        }
        return sb.toString();
    }
    public Map<String, Integer> parse(String formula) {
        Map<String, Integer> map = new TreeMap<>();
        int n = formula.length();
        while(i < n && formula.charAt(i) != ')') {
            if(formula.charAt(i) == '(') {
                i++;
                Map<String, Integer> innerMap = parse(formula);
                for(Map.Entry<String, Integer> entry: innerMap.entrySet()) {
                    map.put(entry.getKey(), entry.getValue() + map.getOrDefault(entry.getKey(), 0));
                }
            } else {
                String letter = "";
                int iStart = i++;
                while(i < n && Character.isLowerCase(formula.charAt(i))) {
                    i++;
                }
                letter = formula.substring(iStart, i);
                iStart = i;
                while(i < n && Character.isDigit(formula.charAt(i))) {
                    i++;
                }
                int count = i == iStart ? 1 : Integer.valueOf(formula.substring(iStart, i));
                if(!letter.isEmpty()) {
                    map.put(letter, map.getOrDefault(letter, 0) + count);
                }
            }
        }
        if(i >= n) return map;
        int iStart = ++i;
        while(i < n && Character.isDigit(formula.charAt(i))) {
            i++;
        }
        int factor = Integer.valueOf(formula.substring(iStart, i));
        for(Map.Entry<String, Integer> entry: map.entrySet()) {
            map.put(entry.getKey(), entry.getValue() * factor);
        }
        return map;
    }
}